home *** CD-ROM | disk | FTP | other *** search
/ TPUG - Toronto PET Users Group / TPUG Users Group CD / TPUG Users Group CD.iso / AMIGA / AMICUS / AMICUS04.ADF / C / speechtoy.c < prev    next >
C/C++ Source or Header  |  1985-11-16  |  41KB  |  1,100 lines

  1. /* speechtoy.c */
  2. /* This program was written to show the use of gadgets in a window.
  3.  * Thus one menu, one auto requester, but lots of gadget types.
  4.  * Also for the sake of example, two mutual exclude gadgets
  5.  * (female/male) are shown that perform a function that might
  6.  * be better implemented as a toggle image, in a manner similar
  7.  * to that shown in the inflection Mode gadget.
  8.  * Yet again for the sake of example, the proportional gadgets
  9.  * are generated dynamicly (that is, copied from a template and
  10.  * filled in), whereas most gadgets are declared staticly in the
  11.  * struct declaration, which saves the initialization code space.
  12.  * Lastly, for the sake of example, this program is extremely
  13.  * verbose in the way of comments. Hope you don't mind.
  14.  */
  15. /* Written by David Lucas */
  16.  
  17. #include "exec/types.h"
  18. #include "exec/exec.h"
  19. #include "intuition/intuition.h"
  20. #include "intuition/intuitionbase.h"
  21. #include "graphics/regions.h"
  22. #include "graphics/copper.h"
  23. #include "graphics/gels.h"
  24. #include "graphics/gfxbase.h"
  25. #include "devices/keymap.h"
  26. #include "hardware/blit.h"
  27. #include "devices/narrator.h"
  28. #include "libraries/translator.h"
  29.  
  30. #define DEBUG
  31.  
  32. /* Revision number is used on calls to OpenLibrary
  33.  * to let the system know what revision level the
  34.  * program was written for. Usually refers to the
  35.  * ROM release number or the release number of a
  36.  * disk based library.
  37.  */
  38. #define REVISION 1
  39.  
  40. #define CONTWINDW 320   /* Overall Control Window Width / Height */
  41. #define CONTWINDH 112
  42. #define FACEWINDW 80    /* Overall Face Window Width / Height */
  43. #define FACEWINDH 50
  44.  
  45. #define YMOUTHCENTER 27 /* Pixels from top edge */
  46. #define XMOUTHCENTER 35 /* Pixels from left edge */
  47.  
  48. /* Pen numbers to draw gadget borders/images/text with */
  49. #define REDP   3        /* color in register 3 once was red */
  50. #define BLKP   2        /* color in register 2 once was black */
  51. #define WHTP   1        /* color in register 1 once was white */
  52. #define BLUP   0        /* color in register 0 once was blue */
  53. #define STRINGSIZE 512  /* the length of the English and phonetic buffers */
  54. #define NUMPROPS 4      /* number of proportional gadgets */
  55.  
  56. #define RNGFREQ  (MAXFREQ  - MINFREQ)  +1 /* Ranges of proportional data */
  57. #define RNGRATE  (MAXRATE  - MINRATE)  +1
  58. #define RNGPITCH (MAXPITCH - MINPITCH) +1
  59. #define RNGVOL   (MAXVOL   - MINVOL)   +1
  60.  
  61. struct TextAttr TestFont = /* Needed for opening screen */
  62.    {
  63.    (STRPTR)"topaz.font",
  64.    TOPAZ_EIGHTY, 0, 0
  65.    };
  66.  
  67. /* speech specific stuff */
  68. BYTE audio_chan[] = {3, 5, 10, 12}; /* Which audio channels to use */
  69. struct Library *TranslatorBase;  /* Pointer to translator library vectors */
  70. struct MsgPort talk_port;        /* Message port for the say's I/O  */
  71. struct MsgPort read_port;        /* Message port for the say's I/O  */
  72. struct narrator_rb voice_io;     /* IO Request block, narrator flavor */
  73. struct mouth_rb mouth_io;        /* IO Request block, narrator flavor */
  74. UBYTE NarratorOpenError = 0;     /* indicative of the Open return */
  75. UBYTE TranslatorError = 0;       /* indicative of a Translations success */
  76. UBYTE NarratorError = 0;         /* indicative of a Narrations success */
  77.  
  78. /* these are used for drawing and erasing the mouth in the face window */
  79. int lastwidth, usedwidth, lastheight, usedheight = 0;
  80.  
  81. /* String Gadgets ******************************************************
  82.  * First the string gadgets.
  83.  * 1) because the Phonetic string is refreshed programaticly (that is,
  84.  * deleted and added again) quite often, and doing this requires the
  85.  * use of RefreshGadgets(), and this causes gadgets that are closer to
  86.  * the beginning of the list than the gadget given to RefreshGadgets()
  87.  * to flicker.
  88.  * 2) because they don't flicker when OTHER gadgets (ie female/male,
  89.  * coming up) are deleted and added.
  90.  */
  91. /* These'll be used to put a nice double line border around
  92.  * each of the two string gadgets.
  93.  */
  94. /* y,x pairs drawn as a connected line. Be sure to have an even
  95.  * number of arguments (ie complete pairs).
  96.  */
  97.  
  98. USHORT StrVectors[] = {
  99.    0, 0,   295, 0,   295, 13,   0, 13,
  100.    0, 1,   294, 1,   294, 12,   1, 12,
  101.    1, 1
  102. };
  103. struct Border StrBorder = {
  104.    -4, -3,     /* initial offsets, gadget relative */
  105.    WHTP, BLUP, JAM1, /* pens (fore, back) and drawmode */
  106.    9,          /* number of vectors */
  107.    StrVectors, /* pointer to the actual array of vectors */
  108.    NULL        /* no next Border, can point to another border */
  109. };
  110.  
  111. /* The same undo buffer is used for both string gadgets,
  112.  * if they were different sizes, this would be sized to largest
  113.  */
  114. UBYTE UndoBuffer[STRINGSIZE];
  115.  
  116. /* English String Gadget is where the user can type in English */
  117. UBYTE EnglBuffer[STRINGSIZE] = "This is amiga speaking.";  /* default text */
  118. struct StringInfo EnglInfo = {
  119.    EnglBuffer,    /* pointer to I/O buffer */
  120.    UndoBuffer,    /* pointer to undo buffer */
  121.    0,             /* buffer position */
  122.    STRINGSIZE,    /* maximum number of chars, including trailing NULL */
  123.    0, 0,          /* first char in display, undo positions */
  124.    24,            /* number of chars (currently) in the buffer */
  125.    0, 0, 0,       /* position variables calculated by Intuition */
  126.    NULL,          /* no pointer to RastPort */
  127.    0,             /* not a LongInt string gadget */
  128.    NULL           /* no pointer to alternate keymap */
  129. };
  130. struct IntuiText EnglText = {
  131.    WHTP, BLUP,    /* FrontPen, BackPen */
  132.    JAM1,          /* DrawMode */
  133.    0, -13,        /* LeftEdge, TopEdge (relative to gadget) */
  134.    &TestFont,     /* pointer to TextFont */
  135.    "English:",    /* pointer to Text */
  136.    NULL           /* no pointer to NextText */
  137. };
  138. struct Gadget EnglStrGadget = {
  139.    NULL,             /* pointer to Next Gadget */
  140.    11, 59, 288, 10,  /* (Left Top Width Height) Hit Box */
  141.    GADGHCOMP,        /* Flags */
  142.    RELVERIFY,        /* Activation flags */
  143.    STRGADGET,        /* Type */
  144.    (APTR)&StrBorder, /* pointer to Border Image */
  145.    NULL,             /* no pointer to SelectRender */
  146.    &EnglText,        /* pointer to GadgetText */
  147.    0,                /* no MutualExclude */
  148.    (APTR)&EnglInfo,  /* pointer to SpecialInfo */
  149.    0,                /* no ID */
  150.    NULL              /* no pointer to special data */
  151. };
  152.  
  153. /* Phonetic string gadget is where the program puts the translated string,
  154.  * necessating a call to RefreshGadgets(),
  155.  * and is where the user can type in Phonemes.
  156.  */
  157. UBYTE PhonBuffer[STRINGSIZE] = "DHIHS IHZ AHMIY3GAH SPIY4KIHNX.";
  158. struct StringInfo PhonInfo = {
  159.    PhonBuffer,    /* pointer to input buffer */
  160.    UndoBuffer,    /* pointer to undo buffer */
  161.    0,             /* initial buffer position */
  162.    STRINGSIZE,    /* maximum number of chars, including trailing NULL */
  163.    0, 0,          /* display, undo positions */
  164.    32,            /* number of chars (currently) in the buffer */
  165.    0, 0, 0,       /* position variables calculated by Intuition */
  166.    NULL,          /* no pointer to RastPort */
  167.    NULL,          /* not a LongInt string gadget */
  168.    NULL           /* no pointer to alternate keymap */
  169. };
  170. struct IntuiText PhonText = {
  171.    WHTP, BLUP,    /* FrontPen, BackPen */
  172.    JAM1,          /* DrawMode */
  173.    0, -13,        /* LeftEdge, TopEdge (relative to gadget) */
  174.    &TestFont,     /* pointer to TextFont */
  175.    "Phonetics:",  /* pointer to Text */
  176.    NULL           /* no pointer to NextText */
  177. };
  178. struct Gadget PhonStrGadget = {
  179.    &EnglStrGadget,   /* pointer to Next Gadget */
  180.    11, 85, 289, 10,  /* (Left Top Width Height) Hit Box */
  181.    GADGHCOMP,        /* Flags */
  182.    RELVERIFY,        /* Activation flags */
  183.    STRGADGET,        /* Type */
  184.    (APTR)&StrBorder, /* pointer to Border Image */
  185.    NULL,             /* no pointer to SelectRender */
  186.    &PhonText,        /* pointer to GadgetText */
  187.    0,                /* no MutualExclude */
  188.    (APTR)&PhonInfo,  /* pointer to SpecialInfo */
  189.    0,                /* no ID */
  190.    NULL              /* no pointer to special data */
  191. };
  192.  
  193. /* Now come the Boolean Gadgets.
  194.  * The female/male pair shows the simplest implementation I could think
  195.  * of to show how you can do mutual-exclude type things yourself.
  196.  * They are two toggle gadgets that use highlight image. The program
  197.  * starts with one selected, and then if either of them are hit,
  198.  * both toggle. Until either of them is hit again.
  199.  * Gadgets must be deleted and added whenever you want to
  200.  * change structure member values that intuition expects to be coming
  201.  * from the user, not a program (like the SELECTED bit in flags).
  202.  * Note that certain structure values CAN be changed programaticly
  203.  * without all this broohaha. Haha. Consult the intuition manual.
  204.  */
  205. /* Female Toggle (Highlight Image) (Quasi mutual exclude with Male Toggle) */
  206. struct Image FemaleImage = {
  207.    0, 0,       /* LeftEdge, TopEdge (relative to gadget) */
  208.    20, 10, 1,  /* Width, Height, Depth */
  209.    NULL,       /* pointer to ImageData */
  210.    0x1, 0x0    /* PlanePick, PlaneOnOff */
  211. };
  212. struct Gadget FemaleGadget = {
  213.    &PhonStrGadget,      /* pointer to Next Gadget */
  214.    134, 34, 20, 10,     /* (Left Top Width Height) Hit Box */
  215.    GADGIMAGE | GADGHCOMP,  /* Flags */
  216.    RELVERIFY | GADGIMMEDIATE | TOGGLESELECT, /* Activation flags */
  217.    BOOLGADGET,          /* Type */
  218.    (APTR)&FemaleImage,  /* pointer to GadgetRender */
  219.    NULL,                /* no pointer to SelectRender */
  220.    NULL,                /* no pointer to GadgetText */
  221.    0,                   /* no MutualExclude */
  222.    NULL,                /* no pointer to SpecialInfo */
  223.    0,                   /* no ID */
  224.    NULL                 /* no pointer to special data */
  225. };
  226.  
  227. /* Male Toggle (Highlight Image) (Quasi mutual Exclude with above) *********/
  228. struct Image MaleImage = {
  229.    0, 0,       /* LeftEdge, TopEdge (relative to gadget) */
  230.    20, 10, 1,  /* Width, Height, Depth */
  231.    NULL,       /* pointer to ImageData */
  232.    0x1, 0x0    /* PlanePick, PlaneOnOff */
  233. };
  234. struct Gadget MaleGadget = {
  235.    &FemaleGadget,    /* pointer to Next Gadget */
  236.    154, 34, 20, 10,  /* (Left Top Width Height) Hit Box */
  237.    GADGIMAGE | GADGHCOMP | SELECTED,   /* Flags */
  238.    RELVERIFY | GADGIMMEDIATE | TOGGLESELECT | ACTIVATE,  /* Activation flags 
  239. */
  240.    BOOLGADGET,       /* Type */
  241.    (APTR)&MaleImage, /* pointer to GadgetRender */
  242.    NULL,             /* no pointer to SelectRender */
  243.    NULL,             /* no pointer to GadgetText */
  244.    0,                /* no MutualExclude */
  245.    NULL,             /* no pointer to SpecialInfo */
  246.    0,                /* no ID */
  247.    NULL              /* no pointer to special data */
  248. };
  249.  
  250. /* This boolean toggle gadget has an alternate image that indicates
  251.  * selection. The image stays flipped until it gets another hit. (it toggles)
  252.  */
  253. /* Inflection Mode Toggle (AltImage) 
  254. ******************************************/
  255. struct Image HumanImage = {
  256.    0, 0,       /* LeftEdge, TopEdge (relative to gadget) */
  257.    40, 20, 1,  /* Width, Height, Depth */
  258.    NULL,       /* pointer to ImageData */
  259.    0x1, 0x0    /* PlanePick, PlaneOnOff */
  260. };
  261. struct Image RobotImage = {
  262.    0, 0,       /* LeftEdge, TopEdge (relative to gadget) */
  263.    40, 20, 1,  /* Width, Height, Depth */
  264.    NULL,       /* pointer to ImageData */
  265.    0x1, 0x0    /* PlanePick, PlaneOnOff */
  266. };
  267. struct Gadget ModeGadget = {
  268.    &MaleGadget,            /* pointer to Next Gadget */
  269.    134, 2, 40, 20,         /* (Left Top Width Height) Hit Box */
  270.    GADGIMAGE | GADGHIMAGE, /* Flags */
  271.    RELVERIFY | GADGIMMEDIATE | TOGGLESELECT,  /* Activation flags */
  272.    BOOLGADGET,             /* Type */
  273.    (APTR)&HumanImage,      /* pointer to GadgetRender */
  274.    (APTR)&RobotImage,      /* pointer to SelectRender */
  275.    NULL,                   /* no pointer to GadgetText */
  276.    0,                      /* no MutualExclude */
  277.    NULL,                   /* no pointer to SpecialInfo */
  278.    0,                      /* no ID */
  279.    NULL                    /* no pointer to special data */
  280. };
  281.  
  282. /* This gadget is diasabled, as the feature is not implemented here.       */
  283. /* Face Toggle (image) *****************************************************/
  284. struct Image FaceImage = {
  285.    0, 0,       /* LeftEdge, TopEdge (relative to gadget) */
  286.    40, 10, 1,  /* Width, Height, Depth */
  287.    NULL,       /* pointer to ImageData */
  288.    0x1, 0x0    /* PlanePick, PlaneOnOff */
  289. };
  290. struct Gadget FaceGadget = {
  291.    &ModeGadget,            /* pointer to Next Gadget */
  292.    134, 23, 40, 10,        /* (Left Top Width Height) Hit Box */
  293.    GADGIMAGE | GADGHCOMP,  /* Flags */
  294.    RELVERIFY | GADGIMMEDIATE | TOGGLESELECT, /* Activation flags */
  295.    BOOLGADGET,             /* Type */
  296.    (APTR)&FaceImage,       /* no pointer to GadgetRender */
  297.    NULL,                   /* no pointer to SelectRender */
  298.    NULL,                   /* pointer to GadgetText */
  299.    0,                      /* no MutualExclude */
  300.    NULL,                   /* no pointer to SpecialInfo */
  301.    0,                      /* no ID */
  302.    NULL                    /* no pointer to special data */
  303. };
  304.  
  305. /* This is a hit (as opposed to toggle) gadget that starts the translation.*/
  306. /* Translate Hit (Highlight image) *****************************************/
  307. USHORT TransVectors[] = {
  308.    1, 0,   74, 0,   74, 9,   1, 9,   1, 0
  309. };
  310. struct Border TransBorder = {
  311.    0, 0,             /* initial offsets, gadget relative */
  312.    WHTP, BLUP, JAM1, /* pens (fore, back) and drawmode */
  313.    5,                /* number of vectors */
  314.    TransVectors,     /* pointer to the actual array of vectors */
  315.    NULL              /* no next Border, can point to another border */
  316. };
  317. struct IntuiText TranslateIText = {
  318.    WHTP, BLUP, /* FrontPen, BackPen */
  319.    JAM2,       /* DrawMode */
  320.    2, 1,       /* LeftEdge, TopEdge (relative to gadget) */
  321.    &TestFont,  /* pointer to TextFont */
  322.    "Translate",/* pointer to Text */
  323.    NULL        /* no pointer to NextText */
  324. };
  325. struct Gadget TranslateGadget = {
  326.    &FaceGadget,      /* pointer to Next Gadget */
  327.    228, 45, 76, 10,  /* (Left Top Width Height) Hit Box */
  328.    GADGHCOMP,        /* Flags */
  329.    RELVERIFY | GADGIMMEDIATE, /* Activation flags */
  330.    BOOLGADGET,       /* Type */
  331.    (APTR)&TransBorder,  /* no pointer to GadgetRender */
  332.    NULL,             /* no pointer to SelectRender */
  333.    &TranslateIText,  /* pointer to GadgetText */
  334.    0,                /* no MutualExclude */
  335.    NULL,             /* no pointer to SpecialInfo */
  336.    0,                /* no ID */
  337.    NULL              /* no pointer to special data */
  338. };
  339.  
  340. /* This is a hit (as opposed to toggle) gadget that starts the narration.  */
  341. /* Speak Hit (Highlight Image) *********************************************/
  342. USHORT SpeakVectors[] = {
  343.    1, 0,   42, 0,   42, 9,   1, 9,   1, 0
  344. };
  345. struct Border SpeakBorder = {
  346.    0, 0,             /* initial offsets, gadget relative */
  347.    WHTP, BLUP, JAM1, /* pens (fore, back) and drawmode */
  348.    5,                /* number of vectors */
  349.    SpeakVectors,     /* pointer to the actual array of vectors */
  350.    NULL              /* no next Border, can point to another border */
  351. };
  352. struct IntuiText SpeakIText = {
  353.    WHTP, BLUP, /* FrontPen, BackPen */
  354.    JAM2,       /* DrawMode */
  355.    2, 1,       /* LeftEdge, TopEdge (relative to gadget) */
  356.    &TestFont,  /* pointer to TextFont */
  357.    "Speak",    /* pointer to Text */
  358.    NULL        /* no pointer to NextText */
  359. };
  360. struct Gadget SpeakGadget = {
  361.    &TranslateGadget, /* pointer to Next Gadget */
  362.    260, 71, 44, 10,  /* (Left Top Width Height) Hit Box */
  363.    GADGHCOMP,        /* Flags */
  364.    RELVERIFY | GADGIMMEDIATE, /* Activation flags */
  365.    BOOLGADGET,       /* Type */
  366.    (APTR)&SpeakBorder,  /* pointer to GadgetRender */
  367.    NULL,             /* no pointer to SelectRender */
  368.    &SpeakIText,      /* pointer to GadgetText */
  369.    0,                /* no MutualExclude */
  370.    NULL,             /* no pointer to SpecialInfo */
  371.    0,                /* no ID */
  372.    NULL              /* no pointer to special data */
  373. };
  374.  
  375. /* Now the proportional gadgets. */
  376. /* Proportional Gadgets **************************************************/
  377. /* The following variables are used to create proportional Gadgets.
  378.  * These variables will be filled in with copies of the generic
  379.  * Gadgetry below.
  380.  */
  381. SHORT PropCount = 0;                   /* index to next available Gadget */
  382. struct IntuiText PTexts[NUMPROPS];     /* these get copies of TPropText */
  383. struct Image PImages[NUMPROPS];        /* dummy AUTOKNOB Images are required 
  384. */
  385. struct PropInfo PInfos[NUMPROPS];      /* these get copies of TPropInfo */
  386. struct Gadget Props[NUMPROPS];         /* these get copies of TPropGadget */
  387. struct IntuiText TPropText = {
  388.    WHTP, BLUP,   /* FrontPen, BackPen */
  389.    JAM1,         /* DrawMode */
  390.    0, -10,       /* LeftEdge, TopEdge (relative to gadget) */
  391.    &TestFont,    /* pointer to TextFont */
  392.    NULL,         /* pointer to Text will be filled at runtime */
  393.    NULL          /* no pointer to NextText */
  394. };   
  395. struct PropInfo TPropInfo = {
  396.    AUTOKNOB | FREEHORIZ,  /* Flags */
  397.    0, 0,            /* Pots:  Horiz, Vert: both start at 0 */
  398.    0x1FFF, 0x1FFF,  /* Bodies: Horiz is 1/8, Vert is 1/8 */
  399.    0, 0, 0, 0, 0, 0 /* System usage stuff */
  400. };
  401. /* this is the template for the Gadget of a horizontal Proportional Gadget */
  402. struct Gadget TPropGadget = {
  403.    &SpeakGadget,              /* pointer to NextGadget */
  404.    7, 12, 115, 10,            /* Select Box Left Top Width Height */
  405.    GADGHCOMP | GADGIMAGE,     /* Flags */
  406.    GADGIMMEDIATE | RELVERIFY, /* Activation flags */
  407.    PROPGADGET,                /* Type */
  408.    NULL,       /* pointer to Image filled in later since this is AUTOKNOB */
  409.    NULL,       /* no pointer to SelectRender */
  410.    NULL,       /* no pointer to GadgetText */
  411.    0,          /* no MutualExclude */
  412.    NULL,       /* SpecialInfo proportional data filled in later */
  413.    0,          /* no ID */
  414.    NULL        /* no pointer to special data */
  415. };
  416.  
  417. struct IntuitionBase *IntuitionBase;
  418. struct GfxBase *GfxBase;
  419.  
  420. /* Only one menu. Most of you (I assume) are as egocentric as I am.
  421.  * If so, this menu and the requster involved are a must do.
  422.  */
  423.  
  424. ULONG MenuNumber;
  425. ULONG TheMenu;
  426. ULONG TheItem;
  427.  
  428. struct IntuiText MenuItemText = {
  429.    BLUP,         /* Front Pen */
  430.    WHTP,         /* Back pen */
  431.    JAM2,         /* Draw Mode */
  432.    0,            /* Left Edge */
  433.    0,            /* Top */
  434.    &TestFont,    /* pointer to TextFont */
  435.    "About SpeechToy...", /* text */
  436.    NULL          /* next */
  437. };
  438. struct MenuItem MyMenuItem = {
  439.    NULL,                /* pointer to next item */
  440.    0,                   /* left */
  441.    0,                   /* top */
  442.    150,                 /* width */
  443.    8,                   /* height */
  444.    ITEMTEXT | ITEMENABLED | HIGHCOMP,  /* flags */
  445.    0,                   /* no mutual exclude */
  446.    (APTR)&MenuItemText, /* Render */
  447.    NULL,                /* pointer to alternate image */
  448.    NULL,                /* Command "amiga" char */
  449.    NULL,                /* Sub Item */
  450.    MENUNULL             /* nextselect */
  451. };
  452.  
  453. struct Menu MyMenu = {
  454.    NULL,          /* pointer to next menu */
  455.    0,0,120,0,     /* left,0,Width,0 */
  456.    MENUENABLED,   /* flags */
  457.    "SpeechToy Menu",   /* menu name */
  458.    &MyMenuItem    /* First Item in list */
  459. };
  460.  
  461. struct IntuiText ReqText1 = {
  462.    BLUP,         /* Front Pen */
  463.    WHTP,         /* Back pen */
  464.    JAM2,         /* Draw Mode */
  465.    5,            /* Left Edge */
  466.    23,           /* Top */
  467.    &TestFont,    /* pointer to TextFont */
  468.    "AnyTown, USA        91827",  /* text */
  469.    NULL          /* next */
  470. };
  471. struct IntuiText ReqText2 = {
  472.    BLUP,         /* Front Pen */
  473.    WHTP,         /* Back pen */
  474.    JAM2,         /* Draw Mode */
  475.    5,            /* Left Edge */
  476.    13,           /* Top */
  477.    &TestFont,    /* pointer to TextFont */
  478.    "12345 Main Street,       ", /* text */
  479.    &ReqText1     /* next */
  480. };
  481. struct IntuiText ReqText3 = {
  482.    BLUP,         /* Front Pen */
  483.    WHTP,         /* Back pen */
  484.    JAM2,         /* Draw Mode */
  485.    5,            /* Left Edge */
  486.    3,            /* Top */
  487.    &TestFont,    /* pointer to TextFont */
  488.    "David M. Lucas,          ", /* text */
  489.    &ReqText2     /* next */
  490. };
  491.  
  492. struct IntuiText OKIText = {
  493.    BLUP, WHTP, /* FrontPen, BackPen */
  494.    JAM2,       /* DrawMode */
  495.    6, 3,       /* LeftEdge, TopEdge (relative to gadget) */
  496.    &TestFont,  /* pointer to TextFont */
  497.    "OK",       /* pointer to Text */
  498.    NULL        /* no pointer to NextText */
  499. };
  500.  
  501. struct Requester *AboutRequester;
  502.  
  503. USHORT autoret;
  504. struct Window *ControlWindow;
  505. struct Window *FaceWindow;
  506. struct IntuiMessage *MyIntuiMessage;
  507. struct NewWindow NewControlWindow = {
  508.    00, 11,                    /* start LeftEdge, TopEdge */
  509.    CONTWINDW, CONTWINDH,      /* start Width, Height */
  510.    -1, -1,                    /* DetailPen, BlockPen */
  511.    GADGETUP | CLOSEWINDOW | MENUPICK,  /* IDCMP FLAGS (can be NULL) */
  512.    WINDOWDRAG | WINDOWDEPTH | WINDOWCLOSE
  513.    | GIMMEZEROZERO | ACTIVATE,/* Flags (can be NULL) */
  514.    &Props[NUMPROPS-1],        /* Pointer to FirstGadget */
  515.    NULL,                      /* no pointer to first CheckMark */
  516.    "SpeechToy",               /* Title (can be NULL) */
  517.    NULL,                      /* no Pointer to Screen */
  518.    NULL,                      /* no Pointer to BitMap */
  519.    20, 20,                    /* Minimum Sizable to (w/h) */
  520.    CONTWINDW, CONTWINDH,      /* Maximum Sizable to (w/h) */
  521.    WBENCHSCREEN               /* Type of screen window appears in */
  522. };
  523.  
  524. struct NewWindow NewFaceWindow = {
  525.    CONTWINDW, 11,             /* start LeftEdge, TopEdge */
  526.    FACEWINDW, FACEWINDH,      /* start Width, Height */
  527.    -1, -1,                    /* DetailPen, BlockPen */
  528.    NULL,                      /* IDCMP FLAGS */
  529.    WINDOWDRAG | WINDOWDEPTH | GIMMEZEROZERO | ACTIVATE,/* Flags (can be NULL) 
  530. */
  531.    NULL,                      /* no Pointer to FirstGadget */
  532.    NULL,                      /* no Pointer to first CheckMark */
  533.    NULL,                      /* no Title */
  534.    NULL,                      /* no Pointer to Screen */
  535.    NULL,                      /* no Pointer to BitMap */
  536.    20, 20,                    /* Minimum Sizable to (w/h) (not sizeable) */
  537.    FACEWINDW, FACEWINDH,      /* Maximum Sizable to (w/h) (not sizeable) */
  538.    WBENCHSCREEN               /* Type of screen window appears in */
  539. };
  540.  
  541. USHORT FemaleIData[] = {
  542. /*   ----    -  These nibbles matter to image. */
  543.    0x0000, 0x0000,
  544.    0x00F0, 0x0000,
  545.    0x0198, 0x0000,
  546.    0x030C, 0x0000,
  547.    0x0198, 0x0000,
  548.    0x00F0, 0x0000,
  549.    0x0060, 0x0000,
  550.    0x01F8, 0x0000,
  551.    0x0060, 0x0000,
  552.    0x0000, 0x0000
  553. };
  554.  
  555. USHORT MaleIData[] = {
  556. /*   ----    -   These nibbles matter to image. */
  557.    0x0000, 0x0000,
  558.    0x003E, 0x0000,
  559.    0x000E, 0x0000,
  560.    0x0036, 0x0000,
  561.    0x01E0, 0x0000,
  562.    0x0330, 0x0000,
  563.    0x0618, 0x0000,
  564.    0x0330, 0x0000,
  565.    0x01E0, 0x0000,
  566.    0x0000, 0x0000
  567. };
  568. USHORT HumanIData[] = {
  569. /*   ----   ----   --   These nibbles matter to image. */
  570.    0x0000,0x0000,0x0000,
  571.    0x0000,0x0000,0x0000,
  572.    0x0000,0x0000,0x0000,
  573.    0x0000,0x0000,0x0000,
  574.    0x0007,0x9E00,0x0000,
  575.    0x0001,0x8600,0x0000,
  576.    0x0000,0x0000,0x0000,
  577.    0x0000,0x0000,0x0000,
  578.    0x0000,0x2000,0x0000,
  579.    0x0000,0x1000,0x0000,
  580.    0x0000,0x0800,0x0000,
  581.    0x0000,0x7C00,0x0000,
  582.    0x0000,0x0000,0x0000,
  583.    0x0000,0x0000,0x0000,
  584.    0x0000,0x0000,0x0000,
  585.    0x0000,0x7800,0x0000,
  586.    0x0000,0x0000,0x0000,
  587.    0x0000,0x0000,0x0000,
  588.    0x0000,0x0000,0x0000,
  589.    0x0000,0x0000,0x0000
  590. };
  591. USHORT RobotIData[] = {
  592. /*   ----   ----   --   These nibbles matter to image. */
  593.    0x0000,0x0000,0x0000,
  594.    0x0000,0x0000,0x0000,
  595.    0x0000,0x0000,0x0000,
  596.    0x0000,0x0000,0x0000,
  597.    0x0007,0x9E00,0x0000,
  598.    0x0004,0x9200,0x0000,
  599.    0x0007,0x9E00,0x0000,
  600.    0x0000,0x0000,0x0000,
  601.    0x0000,0x0000,0x0000,
  602.    0x0000,0x0000,0x0000,
  603.    0x0000,0x0000,0x0000,
  604.    0x0000,0x0000,0x0000,
  605.    0x0000,0x0000,0x0000,
  606.    0x0001,0xF800,0x0000,
  607.    0x0001,0x0800,0x0000,
  608.    0x0001,0xF800,0x0000,
  609.    0x0000,0x0000,0x0000,
  610.    0x0000,0x0000,0x0000,
  611.    0x0000,0x0000,0x0000,
  612.    0x0000,0x0000,0x0000
  613. };
  614. USHORT FaceIData[] = {
  615. /*   ----    ----    --  These nibbles matter to image. */
  616.    0x0000, 0x0000, 0x0000,
  617.    0x0000, 0x1800, 0x0000,
  618.    0x0000, 0x0000, 0x0000,
  619.    0x0000, 0x0000, 0x0000,
  620.    0x2000, 0x0000, 0x0400,
  621.    0x2000, 0x0000, 0x0400,
  622.    0x0000, 0x0000, 0x0000,
  623.    0x0000, 0x0000, 0x0000,
  624.    0x0000, 0x1800, 0x0000,
  625.    0x0000, 0x0000, 0x0000
  626. };
  627. USHORT *FemaleIData_chip;
  628. USHORT *MaleIData_chip;
  629. USHORT *HumanIData_chip;
  630. USHORT *RobotIData_chip;
  631. USHORT *FaceIData_chip;
  632.  
  633. /** start of code ***************************/
  634. main()
  635. {
  636.    /* Open those libraries that the program uses directly */
  637.    if ((IntuitionBase = (struct IntuitionBase *)
  638.     OpenLibrary("intuition.library", REVISION)) == 0) {
  639. #ifdef DEBUG
  640.       printf("Can't open the intuition library\n");
  641. #endif
  642.       MyCleanup();
  643.       Exit(FALSE);
  644.    }
  645.  
  646.    if ((GfxBase = (struct GfxBase *)
  647.     OpenLibrary("graphics.library", REVISION)) == 0) {
  648. #ifdef DEBUG
  649.       printf("Can't open the graphics library\n");
  650. #endif
  651.       MyCleanup();
  652.       Exit(FALSE);
  653.    }
  654.  
  655.    if ((TranslatorBase = (struct Library *)
  656.     OpenLibrary("translator.library", REVISION)) == 0) {
  657. #ifdef DEBUG
  658.       printf("Can't open the translator library\n");
  659. #endif
  660.       MyCleanup();
  661.       Exit(FALSE);
  662.    }
  663.  
  664.    /* Open the device */
  665.    if ((NarratorOpenError = OpenDevice("narrator.device", 0, &voice_io, 0)) != 0) {
  666. #ifdef DEBUG
  667.       printf("Can't open the narrator device\n");
  668. #endif
  669.       MyCleanup();
  670.       Exit(FALSE);
  671.    }
  672.    /* This is where the proportional gadgets are set up, using
  673.     * the templates that were declared staticly.
  674.     */
  675.    for(PropCount = 0; PropCount < NUMPROPS; PropCount++) {
  676.       PTexts[PropCount] = TPropText;
  677.       Props[PropCount] = TPropGadget;
  678.       PInfos[PropCount] = TPropInfo;
  679.       Props[PropCount].GadgetText = (struct IntuiText *)&PTexts[PropCount];
  680.       Props[PropCount].GadgetRender = (APTR)&PImages[PropCount];
  681.       Props[PropCount].SpecialInfo = (APTR)&PInfos[PropCount];
  682.       switch (PropCount) {
  683.       case 0:
  684.          PTexts[PropCount].IText = "Sample Freq:";
  685.          if (DEFFREQ == MAXFREQ)
  686.             PInfos[PropCount].HorizPot = 65535;
  687.          else
  688.             PInfos[PropCount].HorizPot = ((DEFFREQ - MINFREQ) << 16) / (MAXFREQ 
  689. - MINFREQ);
  690.          break;
  691.       case 1:
  692.          PTexts[PropCount].IText = "Rate:";
  693.          Props[PropCount].TopEdge += 22;
  694.          Props[PropCount].NextGadget = &Props[PropCount-1];
  695.          if (DEFRATE == MAXRATE)
  696.             PInfos[PropCount].HorizPot = 65535;
  697.          else
  698.             PInfos[PropCount].HorizPot = ((DEFRATE - MINRATE) << 16) / (MAXRATE 
  699. - MINRATE);
  700.          break;
  701.       case 2:
  702.          PTexts[PropCount].IText = "Pitch:";
  703.          Props[PropCount].LeftEdge += 181;
  704.          Props[PropCount].NextGadget = &Props[PropCount-1];
  705.          if (DEFPITCH == MAXPITCH)
  706.             PInfos[PropCount].HorizPot = 65535;
  707.          else
  708.             PInfos[PropCount].HorizPot = ((DEFPITCH - MINPITCH) << 16) / 
  709. (MAXPITCH - MINPITCH);
  710.          break;
  711.       case 3:
  712.          PTexts[PropCount].IText = "Volume:";
  713.          Props[PropCount].TopEdge += 22;
  714.          Props[PropCount].LeftEdge += 181;
  715.          Props[PropCount].NextGadget = &Props[PropCount-1];
  716.          if (DEFVOL == MAXVOL)
  717.             PInfos[PropCount].HorizPot = 65535;
  718.          else
  719.             PInfos[PropCount].HorizPot = ((DEFVOL - MINVOL) << 16) / (MAXVOL - 
  720. MINVOL);
  721.          break;
  722. /* the following for lattice bug */
  723.       case 4: break;
  724.       }
  725.    }
  726.  
  727.    /* Now allocate memory accessable by the chips for images */
  728.    if (InitImages() != TRUE) {
  729. #ifdef DEBUG
  730.       printf("Couldn't Allocate Images in chip memory.\n");
  731. #endif
  732.       MyCleanup();
  733.       Exit(FALSE);
  734.    }
  735.  
  736.    /* Set up the write port, allocate the signal, and the message */
  737.    talk_port.mp_Node.ln_Type = NT_MSGPORT;
  738.    talk_port.mp_Flags = 0;
  739.    if ((talk_port.mp_SigBit = AllocSignal(-1)) == -1) {
  740. #ifdef DEBUG
  741.       printf("Couldn't Allocate talk Signal bit\n");
  742. #endif
  743.       MyCleanup();
  744.       Exit(FALSE);
  745.    }
  746.    talk_port.mp_SigTask = (struct Task *) FindTask((char *) NULL);
  747.    NewList(&talk_port.mp_MsgList);
  748.  
  749.    /* Set up the read port, allocate the signal, and the message */
  750.    read_port.mp_Node.ln_Type = NT_MSGPORT;
  751.    read_port.mp_Flags = 0;
  752.    if ((read_port.mp_SigBit = AllocSignal(-1)) == -1) {
  753. #ifdef DEBUG
  754.       printf("Couldn't Allocate read Signal bit\n");
  755. #endif
  756.       MyCleanup();
  757.       Exit(FALSE);
  758.    }
  759.    read_port.mp_SigTask = (struct Task *) FindTask((char *) NULL);
  760.    NewList(&read_port.mp_MsgList);
  761.  
  762.    /* Set up the write channel information */
  763.    voice_io.ch_masks = (audio_chan);
  764.    voice_io.nm_masks = sizeof(audio_chan);
  765.    voice_io.mouths = 0;
  766.    voice_io.message.io_Message.mn_ReplyPort = &talk_port;
  767.    voice_io.message.io_Command = CMD_WRITE;
  768.    voice_io.message.io_Offset = 0;
  769.    voice_io.message.io_Data = (APTR)PhonBuffer;
  770.    voice_io.message.io_Length = strlen(PhonBuffer);
  771.    voice_io.message.io_Message.mn_Length = sizeof(voice_io);
  772.  
  773.    /* Set up the read channel information */
  774.    mouth_io.voice = voice_io;
  775.    mouth_io.width = 0;
  776.    mouth_io.height = 0;
  777.    mouth_io.voice.message.io_Message.mn_ReplyPort = &read_port;
  778.    mouth_io.voice.message.io_Command = CMD_READ;
  779.    mouth_io.voice.message.io_Error = 0;
  780.    if ((ControlWindow = (struct Window *)OpenWindow(&NewControlWindow)) == 
  781. NULL) {
  782. #ifdef DEBUG
  783.       printf("Couldn't open the control window.\n");
  784. #endif
  785.       MyCleanup();
  786.       Exit(FALSE);
  787.    }
  788.  
  789.    /* fill background of window */
  790.    SetAPen(ControlWindow->RPort, BLKP);
  791.    RectFill(ControlWindow->RPort,0,0,CONTWINDW,CONTWINDH);
  792.    RefreshGadgets(&Props[NUMPROPS-1],ControlWindow,NULL);
  793.  
  794.    SetMenuStrip(ControlWindow, &MyMenu);
  795.  
  796.    for (;;) {  /* ever wait for a signal and process it */
  797.       /* wait lets the rest of the system run, this program sleeps */
  798.       Wait(1 << ControlWindow->UserPort->mp_SigBit);
  799.       /* now check to see to what we owe the intrusion */
  800.       while (MyIntuiMessage=(struct IntuiMessage *)
  801.                         GetMsg(ControlWindow->UserPort))
  802.       switch (MyIntuiMessage->Class) {
  803.          case MENUPICK:
  804.             ReplyMsg(MyIntuiMessage);
  805.             menumessage(MyIntuiMessage, ControlWindow);
  806.             break;
  807.          case GADGETUP:                   /* reply, then process */
  808.             ReplyMsg(MyIntuiMessage);
  809.             gadgetmessage(MyIntuiMessage, ControlWindow);
  810.             break;
  811.          case CLOSEWINDOW:                /* bye */
  812.             ReplyMsg(MyIntuiMessage);
  813.             while (MyIntuiMessage = (struct IntuiMessage *)
  814.             GetMsg(ControlWindow->UserPort))
  815.               ReplyMsg(MyIntuiMessage);
  816.             MyCleanup();
  817.             Exit(TRUE);
  818.             break;
  819.          default:
  820.             ReplyMsg(MyIntuiMessage);
  821. #ifdef DEBUG
  822.             printf("Unhandled Message Received.\n");
  823. #endif
  824.             break;
  825.       }  /* switch */
  826.    }  /* for */
  827. }  /* main */
  828.  
  829. /* a MENUPICK has been received, this routine takes the appropriate action */
  830. menumessage(message, w)
  831. struct IntuiMessage *message;
  832. struct Window *w;
  833. {
  834.    USHORT code;
  835.    code = (message->Code);
  836.    switch (MENUNUM(code)) {
  837.       case 0:
  838.          switch (ITEMNUM(code)) {
  839.             case 0:
  840.                AutoRequest(ControlWindow, &ReqText3, NULL, &OKIText, 0, 0, 280, 
  841. 47);
  842.                break;
  843.          }
  844.       break;
  845.    }
  846. }
  847.  
  848. /* a GADGETUP has been received, this routine takes the appropriate action */
  849. gadgetmessage(message, w)
  850. struct IntuiMessage *message;
  851. struct Window *w;
  852. {
  853.    USHORT i;
  854.    long PropRange;
  855.    if (message->IAddress == (APTR)&ModeGadget) {
  856.       if (ModeGadget.Flags & SELECTED)
  857.          voice_io.mode = ROBOTICF0;
  858.       else
  859.          voice_io.mode = NATURALF0;
  860.    }
  861.    else if (message->IAddress == (APTR)&FaceGadget) {
  862.       if (FaceGadget.Flags & SELECTED) {
  863.          voice_io.mouths = 1;    /* tell the write that reads will be 
  864. forthcomming */
  865.          if ((FaceWindow = (struct Window *)OpenWindow(&NewFaceWindow)) == 
  866. NULL) {
  867. #ifdef DEBUG
  868.             printf("Couldn't open the mouth window.\n");
  869. #endif
  870.             MyCleanup();
  871.             Exit(FALSE);
  872.          }
  873.          SetAPen(FaceWindow->RPort, WHTP);  /* Set pen to White */
  874.          RectFill(FaceWindow->RPort, 0, 0, FACEWINDW, FACEWINDH);
  875.  
  876.          SetAPen(FaceWindow->RPort, BLUP);  /* Set pen to Blue */
  877.          RectFill(FaceWindow->RPort, 10, 10, 20, 15);
  878.          RectFill(FaceWindow->RPort, 50, 10, 60, 15);
  879.  
  880.          SetAPen(FaceWindow->RPort, REDP);  /* Set pen to Red */
  881.          RectFill(FaceWindow->RPort, XMOUTHCENTER-15, YMOUTHCENTER, 
  882. XMOUTHCENTER+15, YMOUTHCENTER);
  883.       }
  884.       else {
  885.          voice_io.mouths = 0;
  886.          CloseWindow(FaceWindow);
  887.          FaceWindow = NULL;
  888.       }
  889.    }
  890.    /* Since this program changes a flag that intuition expects only
  891.     * the user to change (SELECTED bit), this program has to remove,
  892.     * then change, then add this gadget. Then by passing the address
  893.     * of this gadget to RefreshGadgets(), only the gadgets from here
  894.     *  to the start of the list will be refreshed, which minimizes
  895.     * the visible flash that RefreshGadgets() can introduce.
  896.     * If one of the two gadgets (female/male) is hit, toggle the
  897.     * selection of the other gadget (since the gadget hit was toggled
  898.     * by intuition when it was hit).
  899.     */
  900.    else if (message->IAddress == (APTR)&FemaleGadget) {
  901.       if (FemaleGadget.Flags & SELECTED)
  902.       voice_io.sex = FEMALE;
  903.       else
  904.       voice_io.sex = MALE;
  905.       i = RemoveGadget(ControlWindow, &MaleGadget);
  906.       MaleGadget.Flags ^= SELECTED;
  907.       AddGadget(ControlWindow, &MaleGadget, i);
  908.       RefreshGadgets(&MaleGadget, ControlWindow, NULL);
  909.    }
  910.    else if (message->IAddress == (APTR)&MaleGadget) {
  911.       if (MaleGadget.Flags & SELECTED)
  912.       voice_io.sex = MALE;
  913.       else
  914.       voice_io.sex = FEMALE;
  915.       i = RemoveGadget(ControlWindow, &FemaleGadget);
  916.       FemaleGadget.Flags ^= SELECTED;
  917.       AddGadget(ControlWindow, &FemaleGadget, i);
  918.       RefreshGadgets(&MaleGadget, ControlWindow, NULL);
  919.    }
  920.    /* Since the program changes the contents of the string gadgets'
  921.     * buffer and it's size, which is something else intuition doesn't
  922.     * expect a program (as opposed to the user) to do. The program
  923.     * must remove, then change, then add this gadget, and then by
  924.     * passing the address of this gadget to RefreshGadgets(), only the
  925.     * gadgets from here to the start of the list will be refreshed,
  926.     * which minimizes the visible flash that RefreshGadgets() can introduce.
  927.     */
  928.    else if (message->IAddress == (APTR)&TranslateGadget) {
  929.       i = RemoveGadget(ControlWindow, &PhonStrGadget);
  930.       if ((TranslatorError = Translate((APTR)EnglBuffer, EnglInfo.NumChars, 
  931. (APTR)PhonBuffer, PhonInfo.MaxChars)) != 0) {
  932. #ifdef DEBUG
  933.          printf("Translator won't. (%lx)\n",TranslatorError);
  934. #endif
  935.          DisplayBeep(ControlWindow->WScreen);  /* flash this screen */
  936.       }
  937.       voice_io.message.io_Length = strlen(PhonBuffer);
  938.       /* Hey! NumChars includes the terminating NULL. This must be done. */
  939.       PhonInfo.NumChars = voice_io.message.io_Length + 1;
  940.       AddGadget(ControlWindow, &PhonStrGadget, i);
  941.       RefreshGadgets(&PhonStrGadget, ControlWindow, NULL);
  942.    }
  943.    else if (message->IAddress == (APTR)&SpeakGadget) {
  944.       if ((NarratorError = SendIO(&voice_io)) != 0) {
  945. #ifdef DEBUG
  946.          printf("Narrator won't. (%lx)\n",NarratorError);
  947. #endif
  948.          DisplayBeep(ControlWindow->WScreen);  /* flash this screen */
  949.       }
  950.       else {
  951.          if (voice_io.mouths == 1) {
  952.             while(mouth_io.voice.message.io_Error != ND_NoWrite) {
  953.                DoIO(&mouth_io);
  954.                SetAPen(FaceWindow->RPort, WHTP);
  955.                RectFill(FaceWindow->RPort,XMOUTHCENTER-usedwidth,
  956.                 YMOUTHCENTER-usedheight,XMOUTHCENTER+usedwidth,
  957.                 (YMOUTHCENTER-usedheight)+lastheight);
  958.                lastwidth = mouth_io.width;
  959.                usedwidth = (lastwidth >> 1) + lastwidth;
  960.                lastheight = mouth_io.height;
  961.                usedheight = lastheight >> 1;
  962.                SetAPen(FaceWindow->RPort, REDP);
  963.                Move(FaceWindow->RPort, XMOUTHCENTER - usedwidth, YMOUTHCENTER);
  964.                Draw(FaceWindow->RPort, XMOUTHCENTER, YMOUTHCENTER - usedheight);
  965.                Draw(FaceWindow->RPort, XMOUTHCENTER + usedwidth, YMOUTHCENTER);
  966.                Draw(FaceWindow->RPort, XMOUTHCENTER, YMOUTHCENTER + (mouth_io.height - usedheight));
  967.                Draw(FaceWindow->RPort, XMOUTHCENTER - usedwidth, YMOUTHCENTER);
  968.             }
  969.             mouth_io.voice.message.io_Error = 0;
  970.          }
  971.       }
  972.    }
  973.    else if (message->IAddress == (APTR)&EnglStrGadget);  /* do nothing */
  974.    else if (message->IAddress == (APTR)&PhonStrGadget);  /* do nothing */
  975.    else if (message->IAddress == (APTR)&Props[0]) {
  976.       PropRange = RNGFREQ;
  977.       voice_io.sampfreq = (( (PInfos[0].HorizPot >> 1) * PropRange) >> 15) + MINFREQ;
  978. #ifdef DEBUG
  979.       printf("Freq. = %ld\n", voice_io.sampfreq);
  980. #endif
  981.    }
  982.    else if (message->IAddress == (APTR)&Props[1]) {
  983.       PropRange = RNGRATE;
  984.       voice_io.rate = (((PInfos[1].HorizPot >> 1) * PropRange) >> 15) + MINRATE;
  985. #ifdef DEBUG
  986.       printf("Rate  = %ld\n", voice_io.rate);
  987. #endif
  988.    }
  989.    else if (message->IAddress == (APTR)&Props[2]) {
  990.       PropRange = RNGPITCH;
  991.       voice_io.pitch = (((PInfos[2].HorizPot >> 1) * PropRange) >> 15) + MINPITCH;
  992. #ifdef DEBUG
  993.       printf("Pitch = %ld\n", voice_io.pitch);
  994. #endif
  995.    }
  996.    else if (message->IAddress == (APTR)&Props[3]) {
  997.       PropRange = RNGVOL;
  998.       voice_io.volume = (((PInfos[3].HorizPot >> 1) * PropRange) >> 15) + MINVOL;
  999. #ifdef DEBUG
  1000.       printf("Vol.  = %ld\n", voice_io.volume);
  1001. #endif
  1002.    }
  1003. #ifdef DEBUG
  1004.    else printf("Unhandled gadget up received!\n");
  1005. #endif
  1006. }
  1007.  
  1008. /* Deallocate any memory, and close all windows/screens/devices/libraries
  1009.  * in reverse order to make programming easier. And be sure to check
  1010.  * that the open/allocation was successful before closing/deallocating.
  1011.  */
  1012. MyCleanup()
  1013. {
  1014.    if (read_port.mp_SigBit != -1)
  1015.       FreeSignal(talk_port.mp_SigBit);
  1016.    if (talk_port.mp_SigBit != -1)
  1017.       FreeSignal(talk_port.mp_SigBit);
  1018.    if (FaceWindow != 0)
  1019.       CloseWindow(FaceWindow);
  1020.    if (ControlWindow != 0)
  1021.       CloseWindow(ControlWindow);
  1022.    /* freeimages makes sure image allocation was successful */
  1023.    freeimages();
  1024.    if (NarratorOpenError == 0)
  1025.       CloseDevice(&voice_io);
  1026.    if (TranslatorBase != 0)
  1027.       CloseLibrary(TranslatorBase);
  1028.    if (GfxBase != 0)
  1029.       CloseLibrary(GfxBase);
  1030.    if (IntuitionBase != 0)
  1031.       CloseLibrary(IntuitionBase);
  1032.    return(0);
  1033. }
  1034.  
  1035. /* Allocate chip memory for gadget images, and set the pointers in the
  1036.  * corresponding image structures to point to these images.
  1037.  * This must be done because the program could be loaded into expansion
  1038.  * memory (off the side of the box), which the custom chips cannot access.
  1039.  */
  1040.  
  1041. InitImages()
  1042. {
  1043. extern USHORT *FemaleIData_chip;
  1044. extern USHORT *MaleIData_chip;
  1045. extern USHORT *HumanIData_chip;
  1046. extern USHORT *RobotIData_chip;
  1047. extern USHORT *FaceIData_chip;
  1048. int i;
  1049.  
  1050.    if ((FemaleIData_chip = (USHORT *)AllocMem(sizeof(FemaleIData),MEMF_CHIP)) == 0)
  1051.       return(FALSE);
  1052.    if ((MaleIData_chip = (USHORT *)AllocMem(sizeof(MaleIData),MEMF_CHIP)) == 0)
  1053.       return(FALSE);
  1054.    if ((HumanIData_chip = (USHORT *)AllocMem(sizeof(HumanIData),MEMF_CHIP)) == 0)
  1055.       return(FALSE);
  1056.    if ((RobotIData_chip = (USHORT *)AllocMem(sizeof(RobotIData),MEMF_CHIP)) == 0)
  1057.       return(FALSE);
  1058.    if ((FaceIData_chip = (USHORT *)AllocMem(sizeof(FaceIData),MEMF_CHIP)) == 0)
  1059.       return(FALSE);
  1060.  
  1061.    for (i=0; i<20; i++)
  1062.       FemaleIData_chip[i] = FemaleIData[i];
  1063.    for (i=0; i<20; i++)
  1064.       MaleIData_chip[i] = MaleIData[i];
  1065.    for (i=0; i<60; i++)
  1066.       HumanIData_chip[i] = HumanIData[i];
  1067.    for (i=0; i<60; i++)
  1068.       RobotIData_chip[i] = RobotIData[i];
  1069.    for (i=0; i<30; i++)
  1070.       FaceIData_chip[i] = FaceIData[i];
  1071.  
  1072.    FemaleImage.ImageData = FemaleIData_chip;
  1073.    MaleImage.ImageData = MaleIData_chip;
  1074.    HumanImage.ImageData = HumanIData_chip;
  1075.    RobotImage.ImageData = RobotIData_chip;
  1076.    FaceImage.ImageData = FaceIData_chip;
  1077.  
  1078.    return(TRUE);
  1079. }
  1080.  
  1081. freeimages()
  1082. {
  1083.    extern USHORT *FemaleIData_chip;
  1084.    extern USHORT *MaleIData_chip;
  1085.    extern USHORT *HumanIData_chip;
  1086.    extern USHORT *RobotIData_chip;
  1087.    extern USHORT *FaceIData_chip;
  1088.    if (FaceIData_chip != 0)
  1089.       FreeMem(FaceIData_chip, (sizeof(FaceIData),MEMF_CHIP));
  1090.    if (RobotIData_chip != 0)
  1091.       FreeMem(RobotIData_chip, (sizeof(RobotIData),MEMF_CHIP));
  1092.    if (HumanIData_chip != 0)
  1093.       FreeMem(HumanIData_chip, (sizeof(HumanIData),MEMF_CHIP));
  1094.    if (MaleIData_chip != 0)
  1095.       FreeMem(MaleIData_chip, (sizeof(MaleIData),MEMF_CHIP));
  1096.    if (FemaleIData_chip != 0)
  1097.       FreeMem(FemaleIData_chip, (sizeof(FemaleIData),MEMF_CHIP));
  1098. }
  1099.  
  1100.